package com.lean.android.ad.core.splash

import android.app.Activity
import android.app.Application
import android.content.Intent
import android.os.Bundle
import androidx.annotation.RestrictTo
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.lean.android.ad.repository.localcache.AdLocalCache
import com.lean.android.ad.utils.AdLog
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import java.lang.ref.WeakReference

@RestrictTo(RestrictTo.Scope.LIBRARY)
class SplashAdManager : Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {

    private var currentActivityRef = WeakReference<Activity>(null)

    private val appScope by lazy {
        ProcessLifecycleOwner.get().lifecycleScope
    }

    private val _splashAdStateFlow: MutableStateFlow<SplashAdState> =
        MutableStateFlow(SplashAdState.Idle)


    fun updateSplashAdState(newState: SplashAdState) {
        _splashAdStateFlow.value = newState
    }

    fun registerActivityCallbacks(app: Application) {
        app.registerActivityLifecycleCallbacks(this)
    }

    fun getTopActivity(): Activity? {
        return currentActivityRef.get()
    }

    /**
     * 需要再广告初始化完成之后调用
     */
    fun bindToLifecycle() {
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }

    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        if (activity is IColdSplash) {
            AdLog.d(AdLog.AdSplashLoadTag, "code splash launch, set splashAdState to Idle")
            _splashAdStateFlow.value = SplashAdState.Idle
        }
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityCreated ${activity.javaClass.name}")
    }

    override fun onActivityStarted(activity: Activity) {
        currentActivityRef = WeakReference(activity)
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityStarted ${activity.javaClass.name}")
    }

    override fun onActivityResumed(activity: Activity) {
        currentActivityRef = WeakReference(activity)
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityResumed ${activity.javaClass.name}")
    }

    override fun onActivityPaused(activity: Activity) {
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityPaused ${activity.javaClass.name}")
    }

    override fun onActivityStopped(activity: Activity) {
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityStopped ${activity.javaClass.name}")
    }

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        AdLog.d(AdLog.AdSplashLoadTag, "onActivitySaveInstanceState ${activity.javaClass.name}")
    }

    override fun onActivityDestroyed(activity: Activity) {
        currentActivityRef.clear()
        AdLog.d(AdLog.AdSplashLoadTag, "onActivityDestroyed ${activity.javaClass.name}")
    }

    fun close() {
        _splashAdStateFlow.value = SplashAdState.Closed
    }

    private fun canShowSplashAd(activity: Activity): Boolean {
        if (activity is IColdSplash) return true
        return AdLocalCache.canShowSplashAd()
    }

    override fun onStart(owner: LifecycleOwner) {
        super.onStart(owner)
        AdLog.d(AdLog.AdSplashLoadTag, "app enter from background, onStart")
        startSplashAd()
    }

    private fun startSplashAd() {
        if (_splashAdStateFlow.value == SplashAdState.Loading) {
            AdLog.d(AdLog.AdSplashLoadTag, "Splash is loading , skip load.")
            return
        }
        if (_splashAdStateFlow.value == SplashAdState.Shown) {
            AdLog.d(AdLog.AdSplashLoadTag, "Splash is showing , skip load.")
            return
        }

        appScope.launch {
            val currentActivity = currentActivityRef.get()
            if (currentActivity != null) {
                if (canShowSplashAd(currentActivity)) {
                    loadSplashAd(currentActivity)
                } else {
                    close()
                }
            } else {
                close()
            }
        }
    }

    private fun isColdLaunch(): Boolean {
        val currentActivity = currentActivityRef.get()
        return currentActivity != null && currentActivity is IColdSplash
    }

    private fun loadSplashAd(activity: Activity) {
        _splashAdStateFlow.value = SplashAdState.Loading

        val coldLaunch = isColdLaunch()
        AdLog.d(
            AdLog.AdSplashLoadTag,
            "SplashAdManager start to loadSplashAd , coldLaunch $coldLaunch , from activity ${activity.javaClass.name}"
        )

        if (coldLaunch) {//冷开屏
            //冷开屏，由SplashAdLauncherActivity 内部处理，此处不需要
        } else {
            val hotSplashAdIntent =
                Intent(activity, HotSplashAdLauncherActivity::class.java).apply {
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }
            activity.startActivity(hotSplashAdIntent)
        }
    }


}